package ace.tool.generate.code.impl.resolver.scheme.resolver.api;

import ace.cmp.util.CaseFormatUtils;
import ace.tool.generate.code.impl.resolver.scheme.model.bo.api.AuthorityConstantClassInfo;
import ace.tool.generate.code.impl.resolver.scheme.model.bo.api.AuthorityConstantFieldInfo;
import ace.tool.generate.code.impl.resolver.scheme.model.dto.ClassFileInfo;
import ace.tool.generate.code.impl.resolver.scheme.model.dto.CommonInfo;
import ace.tool.generate.code.impl.resolver.scheme.model.dto.ProjectInfo;
import ace.tool.generate.code.impl.resolver.scheme.resolver.ClassFileInfoResolver;
import ace.tool.generate.code.impl.service.model.input.GenerateInput;
import ace.tool.generate.code.impl.service.model.input.GenerateModelInput;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import lombok.Builder;
import lombok.RequiredArgsConstructor;

/**
 * @author caspar
 * @date 2023/11/17 10:34
 */
@Builder
@RequiredArgsConstructor
public class AuthorityConstantClassInfoResolver {
  private final GenerateInput input;
  private final CommonInfo commonInfo;
  private final ProjectInfo apiProjectInfo;

  public AuthorityConstantClassInfo resolve() {
    ClassFileInfo constantClassInfo =
        ClassFileInfoResolver.builder()
            .className(commonInfo.getProjectClassName())
            .classNameSuffix(input.getAuthorityConstantClassNameSuffix())
            .classPackagePrefix(input.getAuthorityConstantClassPackagePrefix())
            .rootPackageFullName(commonInfo.getRootPackageFullName())
            .sourceCodeRootDir(apiProjectInfo.getSourceCodeRootDir())
            .build()
            .resolve();

    return AuthorityConstantClassInfo.builder()
        .info(constantClassInfo)
        .fields(this.getFields())
        .build();
  }

  private List<AuthorityConstantFieldInfo> getFields() {
    return this.input.getModels().stream()
        .map(this::getFieldByModelInput)
        .flatMap(List::stream)
        .collect(Collectors.toList());
  }

  private List<AuthorityConstantFieldInfo> getFieldByModelInput(GenerateModelInput modelInput) {
    return Stream.of(
            "ADMIN_READ",
            "ADMIN_WRITE",
            "ADMIN_REMOVE",
            "TENANT_READ",
            "TENANT_WRITE",
            "TENANT_REMOVE",
            "MERCHANT_READ",
            "MERCHANT_WRITE",
            "MERCHANT_REMOVE",
            "MEMBER_READ",
            "MEMBER_WRITE",
            "MEMBER_REMOVE",
            "CLIENT_READ",
            "CLIENT_WRITE",
            "CLIENT_REMOVE")
        .map(
            suffix -> {
              String name =
                  String.format(
                          "%s_%s", CaseFormatUtils.convertUpperCamelToLowerUnderscore(modelInput.getName()), suffix)
                      .toUpperCase();
              String value = "\"" + name.toLowerCase() + "\"";
              return AuthorityConstantFieldInfo.builder()
                  .type(String.class.getName())
                  .name(name)
                  .value(value)
                  .build();
            })
        .collect(Collectors.toList());
  }
}
